﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BusinessLogicLayer;

namespace PresentationLayer
{
    public partial class frmFinances : Form
    {
        #region Properties
        private frmMain MdiForm { get; set; }
        private enumState State { get; set; }
        enum enumState
        {
            View,
            New,
            Edit
        }
        private Int32 SelectedIndexComboBoxCurrency { get; set; }
        #endregion

        #region Constructors
        public frmFinances(frmMain pMdiForm)
        {
            InitializeComponent();
            this.MdiForm = pMdiForm;
        }
        #endregion

        #region Events
        private void frmFinances_Load(object sender, EventArgs e)
        {
            this.MdiForm.Event_OnTranslationChanged += new frmMain.OnTranslationChangedHandler(Translate);
            Translate();
            FillComboBoxCurrency();
            FillListViewFincances();
            SetButtonsToState(enumState.View);
            SetTextBoxToState(enumState.View);
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            SetButtonsToState(enumState.View);
            SetTextBoxToState(enumState.View);
            FillFieldsWithFinanceDetails();
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            SetButtonsToState(enumState.New);
            SetTextBoxToState(enumState.New);
            dtpDateConcerned.Select();
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            SetButtonsToState(enumState.Edit);
            SetTextBoxToState(enumState.Edit);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            Delete();
        }

        private void lsvFinances_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetButtonsToState(enumState.View);
            SetTextBoxToState(enumState.View);
            FillFieldsWithFinanceDetails();
        }

        private void txtAmount_KeyPress(object sender, KeyPressEventArgs e)
        {
            String DotChar = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
            if ((e.KeyChar <= 57 && e.KeyChar >= 48) || (e.KeyChar == 8 || e.KeyChar == Convert.ToChar(DotChar)))
            {
            }
            else
            {
                e.Handled = true;
            }
        }

        private void cboCurrency_SelectedIndexChanged(object sender, EventArgs e)
        {
            FillComboBoxCurrencyValue();
        }
        #endregion

        #region Public methods
        #endregion

        #region Private methods
        /// <summary>
        /// Fills the currency ComboBox with all actual currencies.
        /// </summary>
        private void FillComboBoxCurrency()
        {
            if (cboCurrency.Items.Count > 0)
            {
                cboCurrency.Items.Clear();
            }

            ArrayList Currencies = this.MdiForm.DataAccess.GetAllCurrencies();
            
            for (Int32 i = 0; i < Currencies.Count; i++)
            {
                clsCurrency Currency = (clsCurrency)Currencies[i];
                if(this.MdiForm.DataAccess.Settings.User_Login.Currency.CurrencyName == Currency.CurrencyName)
                {
                    this.SelectedIndexComboBoxCurrency = i;
                }
                cboCurrency.Items.Add(Currency);
            }

            cboCurrency.SelectedIndex = this.SelectedIndexComboBoxCurrency;
        }

        /// <summary>
        /// Fills the currency value ComboBox.
        /// </summary>
        private void FillComboBoxCurrencyValue()
        {
            if (cboCurrencyValue.Items.Count > 0)
            {
                cboCurrencyValue.Items.Clear();
            }

            clsCurrency Currency = (clsCurrency)cboCurrency.SelectedItem;
            foreach (clsCurrency CurrencyValue in Currency.GetCurrencyValues())
            {
                clsItem Item = new clsItem(CurrencyValue.GetValueAsString(), CurrencyValue);
                cboCurrencyValue.Items.Add(Item);
            }
            cboCurrencyValue.SelectedIndex = 0;
        }

        /// <summary>
        /// Applies the state to the buttons.
        /// </summary>
        /// <param name="pState">The state.</param>
        private void SetButtonsToState(enumState pState)
        {
            this.State = pState;
            switch (this.State)
            {
                case enumState.View:
                    btnCancel.Enabled = false;
                    btnNew.Enabled = true;
                    btnSave.Enabled = false;
                    if (lsvFinances.SelectedItems.Count > 0 && lsvFinances.SelectedItems[0].Index > -1)
                    {
                        btnEdit.Enabled = true;
                        btnDelete.Enabled = true;
                    }
                    else
                    {
                        btnEdit.Enabled = false;
                        btnDelete.Enabled = false;
                    }
                    break;
                case enumState.New:
                    btnCancel.Enabled = true;
                    btnNew.Enabled = false;
                    btnEdit.Enabled = false;
                    btnSave.Enabled = true;
                    btnDelete.Enabled = false;
                    break;
                case enumState.Edit:
                    btnCancel.Enabled = true;
                    btnNew.Enabled = false;
                    btnEdit.Enabled = false;
                    btnSave.Enabled = true;
                    btnDelete.Enabled = false;
                    break;
            }
        }

        /// <summary>
        /// Applies the state to the TextBoxes.
        /// </summary>
        /// <param name="pState">The state.</param>
        private void SetTextBoxToState(enumState pState)
        {
            this.State = pState;
            switch (this.State)
            {
                case enumState.View:
                    lsvFinances.Enabled = true;
                    dtpDateConcerned.Enabled = false;
                    txtDateConcernedHours.Enabled = false;
                    txtDateConcernedMinutes.Enabled = false;
                    txtDescription.Enabled = false;
                    txtAmount.Enabled = false;
                    cboCurrency.Enabled = false;
                    cboCurrencyValue.Enabled = false;
                    break;
                case enumState.New:
                    lsvFinances.Enabled = false;
                    dtpDateConcerned.Enabled = true;
                    txtDateConcernedHours.Enabled = true;
                    txtDateConcernedMinutes.Enabled = true;
                    txtDescription.Enabled = true;
                    txtAmount.Enabled = true;
                    cboCurrency.Enabled = true;
                    cboCurrencyValue.Enabled = true;
                    dtpDateConcerned.Value = DateTime.Now;
                    txtDateConcernedHours.Text = "";
                    txtDateConcernedMinutes.Text = "";
                    txtDescription.Text = "";
                    txtAmount.Text = "";
                    cboCurrency.SelectedIndex = this.SelectedIndexComboBoxCurrency;
                    break;
                case enumState.Edit:
                    lsvFinances.Enabled = false;
                    dtpDateConcerned.Enabled = true;
                    txtDateConcernedHours.Enabled = true;
                    txtDateConcernedMinutes.Enabled = true;
                    txtDescription.Enabled = true;
                    txtAmount.Enabled = true;
                    cboCurrency.Enabled = true;
                    cboCurrencyValue.Enabled = true;
                    break;
            }
        }

        /// <summary>
        /// Translates every visible element.
        /// </summary>
        private void Translate()
        {
            this.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, "Text", this.Text, 0);
            grpDetails.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, grpDetails.Name, grpDetails.Text, 0);
            grpFinances.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, grpFinances.Name, grpFinances.Text, 0);
            lblDateConcerned.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblDateConcerned.Name, lblDateConcerned.Text, 0);
            lblDescription.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblDescription.Name, lblDescription.Text, 0);
            lblAmount.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblAmount.Name, lblAmount.Text, 0);
            lblDateCreated.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblDateCreated.Name, lblDateCreated.Text, 0);
            lblDateChanged.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblDateChanged.Name, lblDateChanged.Text, 0);
            grpOptions.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, grpOptions.Name, grpOptions.Text, 0);
            btnCancel.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, btnCancel.Name, btnCancel.Text, 0);
            btnNew.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, btnNew.Name, btnNew.Text, 0);
            btnEdit.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, btnEdit.Name, btnEdit.Text, 0);
            btnSave.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, btnSave.Name, btnSave.Text, 0);
            btnDelete.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, btnDelete.Name, btnDelete.Text, 0);
            lblCurrency.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblCurrency.Name, lblCurrency.Text, 0);
            FillByFields();
            InitializeListViewFinances();
        }

        /// <summary>
        /// Initializes the stores ListView.
        /// </summary>
        private void InitializeListViewFinances()
        {
            if (lsvFinances.Columns.Count > 0)
            {
                lsvFinances.Columns.Clear();
            }
            lsvFinances.Columns.Add("Date");
            lsvFinances.Columns.Add("Amount");
            lsvFinances.Columns.Add("Description");
            lsvFinances.View = View.Details;
            lsvFinances.FullRowSelect = true;
            lsvFinances.HideSelection = false;
            lsvFinances.MultiSelect = false;
        }

        /// <summary>
        /// Fills the ListView with finances.
        /// </summary>
        /// <param name="pSearchArgument"></param>
        private void FillListViewFincances()
        {
            //Delete all ListView items if available.
            if (lsvFinances.Items.Count > 0)
            {
                lsvFinances.Items.Clear();
            }
            //Get finances.
            ArrayList Finances = this.MdiForm.DataAccess.GetFinances();
            for (Int32 i = 0; i < Finances.Count; i++)
            {
                //Get finance.
                clsFinance Finance = (clsFinance)Finances[i];
                //Create item for ListView.
                ListViewItem Item = new ListViewItem(Finance.GetDateConcerned().ToString());
                Item.SubItems.Add(Finance.Amount.ToString());
                Item.SubItems.Add(Finance.Description);
                Item.Tag = Finance;
                //Add item to ListView.
                lsvFinances.Items.Add(Item);
            }
            //Resize columns adapted to contents.
            lsvFinances.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            //Select the first item if possible.
            if (lsvFinances.Items.Count > 0)
            {
                lsvFinances.Items[0].Selected = true;
            }
            else
            {
                FillFieldsWithFinanceDetails();
            }
        }

        /// <summary>
        /// Get the finance information from the ListView and fill the details into the fields.
        /// </summary>
        private void FillFieldsWithFinanceDetails()
        {
            if (lsvFinances.SelectedItems.Count > 0)
            {
                clsFinance Finance = (clsFinance)lsvFinances.SelectedItems[0].Tag;
                lblDateCreatedVal.Text = Finance.DateCreated.ToString();
                lblDateChangedVal.Text = Finance.DateChanged.ToString();
                lblUserCreatedVal.Text = Finance.UserCreated;
                lblUserChangedVal.Text = Finance.UserChanged;
                dtpDateConcerned.Value = Finance.GetDateConcerned();
                txtDateConcernedHours.Text = Finance.GetDateConcerned().Hour.ToString();
                txtDateConcernedMinutes.Text = Finance.GetDateConcerned().Minute.ToString();
                txtDescription.Text = Finance.Description;
                txtAmount.Text = Finance.Amount.ToString();

                for (Int32 i = 0; i < cboCurrency.Items.Count; i++)
                {
                    clsCurrency Currency = (clsCurrency)cboCurrency.Items[i];
                    if (Currency.CurrencyName == Finance.Currency.CurrencyName)
                    {
                        cboCurrency.SelectedIndex = i;
                        break;
                    }
                }
            }
            else
            {
                lblDateCreatedVal.Text = "";
                lblDateChangedVal.Text = "";
                lblUserCreatedVal.Text = "";
                lblUserChangedVal.Text = "";
                dtpDateConcerned.Value = DateTime.Now;
                txtDateConcernedHours.Text = "";
                txtDateConcernedMinutes.Text = "";
                txtDescription.Text = "";
                txtAmount.Text = "";
                cboCurrency.SelectedIndex = this.SelectedIndexComboBoxCurrency;
            }
            FillByFields();
        }

        /// <summary>
        /// Only fills the "by"-Fields.
        /// </summary>
        private void FillByFields()
        {
            if (lsvFinances.SelectedItems.Count > 0)
            {
                lblCreatedBy.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblCreatedBy.Name, "by", 0);
                lblChangedBy.Text = this.MdiForm.DataAccess.GetTranslation(this.Name, lblChangedBy.Name, "by", 0);
            }
            else
            {
                lblCreatedBy.Text = "";
                lblChangedBy.Text = "";
            }
        }

        /// <summary>
        /// Saves the finance.
        /// </summary>
        private void Save()
        {
            if (SaveFinance())
            {
                FillListViewFincances();
                SetButtonsToState(enumState.View);
                SetTextBoxToState(enumState.View);
            }
        }

        /// <summary>
        /// Deletes a finance.
        /// </summary>
        private void Delete()
        {
            clsFinance Finance = (clsFinance)lsvFinances.SelectedItems[0].Tag;
            switch (MessageBox.Show("Do you really want to delete '" + Finance.Description + "'?", "Delete", MessageBoxButtons.YesNo))
            {
                case DialogResult.Yes:
                    if (this.MdiForm.DataAccess.DeleteFinance(GetFinanceID()))
                    {
                        FillListViewFincances();
                        SetButtonsToState(enumState.View);
                        SetTextBoxToState(enumState.View);
                    }
                    break;
                default:
                    break;
            }

        }

        /// <summary>
        /// Saves the finance depending on the actual state.
        /// </summary>
        /// <returns>State of success.</returns>
        private Boolean SaveFinance()
        {
            Boolean Success = false;
            if (CheckIfTextBoxesEmpty() == false)
            {
                switch (this.State)
                {
                    case enumState.New:
                        Success = this.MdiForm.DataAccess.InsertFinance(GetDateConcerned(), txtDescription.Text, Convert.ToDouble(txtAmount.Text), (clsCurrency)((clsItem)cboCurrencyValue.SelectedItem).GetValues());
                        break;
                    case enumState.Edit:
                        Success = this.MdiForm.DataAccess.ChangeFinance(GetFinanceID(), GetDateConcerned(), txtDescription.Text, Convert.ToDouble(txtAmount.Text), (clsCurrency)((clsItem)cboCurrencyValue.SelectedItem).GetValues());
                        break;
                }
            }
            if (Success == false)
            {
                MessageBox.Show("Error saving store.");
            }
            return Success;
        }

        /// <summary>
        /// Gets the date and time set by the user.
        /// </summary>
        /// <returns>The date and time as DateTime.</returns>
        private DateTime GetDateConcerned()
        {
            return new DateTime(dtpDateConcerned.Value.Year, dtpDateConcerned.Value.Month, dtpDateConcerned.Value.Day, Convert.ToInt32(txtDateConcernedHours.Text), Convert.ToInt32(txtDateConcernedMinutes.Text), 0);
        }

        /// <summary>
        /// Gets the actually selected finance ID.
        /// </summary>
        /// <returns>The ID of the finance.</returns>
        private Int32 GetFinanceID()
        {
            if (lsvFinances.SelectedItems.Count > 0)
            {
                clsFinance Store = (clsFinance)lsvFinances.SelectedItems[0].Tag;
                return Store.ID;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// Checks the emptyness of the TextBoxes.
        /// </summary>
        /// <returns>True if TextBoxes are empty.</returns>
        private Boolean CheckIfTextBoxesEmpty()
        {
            if (txtDateConcernedHours.Text == "")
            {
                return true;
            }

            if (txtDateConcernedMinutes.Text == "")
            {
                return true;
            }

            if (txtDescription.Text == "")
            {
                return true;
            }

            if (txtAmount.Text == "" || txtAmount.Text == "0")
            {
                return true;
            }
            else
            {
                Double OutVar = 0;
                if (Double.TryParse(txtAmount.Text, out OutVar) == false)
                {
                    return true;
                }
            }

            return false;
        }
        #endregion
    }
}
